Date: Wed Feb 12 18:39:20 2020
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong
# Taxonomic Ranks:
# **K**ing **P**hillip **C**an n**O**t **F**ind **G**reen **S**ocks
# * Kingdom
# * Phylum
# * Class
# * Order
# * Family
# * Genus
# * Species
# options(stringsAsFactors = FALSE,
# scipen = 999)
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE,
# message = FALSE,
# warning = FALSE,
# error = FALSE)
# require(knitr)
# require(kableExtra)
require(phyloseq)
Loading required package: phyloseq
# require(shiny)
require(data.table)
Loading required package: data.table
data.table 1.12.2 using 18 threads (see ?getDTthreads). Latest news: r-datatable.com
require(ggplot2)
Loading required package: ggplot2
Need help getting started? Try the cookbook for R: http://www.cookbook-r.com/Graphs/
require(plotly)
Loading required package: plotly
Attaching package: ‘plotly’
The following object is masked from ‘package:ggplot2’:
last_plot
The following object is masked from ‘package:stats’:
filter
The following object is masked from ‘package:graphics’:
layout
require(DT)
Loading required package: DT
require(lmerTest)
Loading required package: lmerTest
Loading required package: lme4
Loading required package: Matrix
Attaching package: ‘lmerTest’
The following object is masked from ‘package:lme4’:
lmer
The following object is masked from ‘package:stats’:
step
source("source/functions_may2019.R")
# On Windows set multithread=FALSE----
mt <- TRUE
Introduction
C57BL/6 wild-type (WT) and Nrf-2 double-knock-out (KO -/-) mice were given 2-week microbiome stabilization process using AIN93M diet and 8 more weeks to treat with either AIN93M or AIN93M 5% PEITC diet. Fecal samples were collected weekly, immediately frozen in liquid nitrogen and stored at -80oC. Serum, cecal, colon epithelial and whole colon tissues at week 10 were also collected for further analyses. Baseline, week 1 and 4 fecal samples were selected for 16s rRNA sequencing.
This document examines results from the WT mice samples.
We will attampt to answer the following questions:
1. Did microbiome change over time?
2. Was microbiome affected by diet?
3. Was there a difference between the KO and WT?
4. If there was a change in microbiome composition, what functional changes did it carry? What are the essential functions of the bacteria affected by the treatment and how can this be shown in vivo (metabolites, inflammation markers, etc.)?
Data preprocessing
Raw Data
FastQ files were downloaded from this Rutgers Box location. A total of 144 files (2 per sample, pair-ended) and a pair of undetermined reads were downloaded.
Samples
ps_sep2019@sam_data$Genotype_Week <- paste(ps_sep2019@sam_data$genotype,
ps_sep2019@sam_data$time,
sep = "_")
ps_sep2019@sam_data$ID <- factor(paste0(ps_sep2019@sam_data$mice_num,
ps_sep2019@sam_data$cage))
ps_sep2019@sam_data$TREATMENT <- paste0(ps_sep2019@sam_data$DSS,
ps_sep2019@sam_data$PEITC,
ps_sep2019@sam_data$cranberry)
ps_sep2019@sam_data$TREATMENT <- factor(ps_sep2019@sam_data$TREATMENT,
levels = c("000",
"100",
"110",
"101"),
labels = c("Naive",
"DSS",
"DSS+PEITC",
"DSS+Cranberry"))
samples <- ps_sep2019@sam_data
datatable(samples,
options = list(pageLength = nrow(samples)))
Prune data
The OTUs were mapped to Bacteria (96.07%), Eukaryota (2.95%) and Archea (0.03%) kingdoms, and 75 OTUs (0.95%) undefined.
The total of 7,867 unique sequences were found. Out of those, 7,558 were mapped to bacterial genomes.
dim(ps_sep2019@otu_table@.Data)
[1] 72 7867
# Remove OTU not mapped to Bacteria
ps0 <- subset_taxa(ps_sep2019,
Kingdom == "Bacteria")
dim(ps0@otu_table@.Data)
[1] 72 7558
Out of the 7,558 OTUs 7,247 belonged to 12 Phyla. 311 of the OTUs (or 4.11% of bacterial OTUs) could not be mapped to a phylum.
t2 <- data.table(table(tax_table(ps0)[, "Phylum"],
exclude = NULL))
t2$V1[is.na(t2$V1)] <- "Unknown"
setorder(t2, -N)
t2[, pct := N/sum(N)]
setorder(t2, -N)
colnames(t2) <- c("Phylum",
"Number of OTUs",
"Percent of OTUs")
datatable(t2,
rownames = FALSE,
caption = "Number of Bacterial OTUs by Phylum",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t2))) %>%
formatCurrency(columns = 2,
currency = "",
mark = ",",
digits = 0) %>%
formatPercentage(columns = 3,
digits = 2)
OTU table (first 10 rows)
Total counts per sample (i.e. sequencing depth)
t1 <- colSums(otu[, 7:ncol(otu)])
t1 <- data.table(SAMPLE_NAME = names(t1),
Total = t1)
t2 <- data.table(SAMPLE_NAME = rownames(samples),
ID = samples$ID,
CAGE = samples$cage,
TREATMENT = samples$TREATMENT,
Genotype = samples$genotype,
WEEK = samples$time)
smpl <- merge(t1,
t2,
by = "SAMPLE_NAME")
p1 <- ggplot(smpl,
aes(x = SAMPLE_NAME,
y = Total,
fill = TREATMENT,
colour = WEEK)) +
facet_wrap(~ Genotype,
scale = "free_x") +
geom_bar(stat = "identity") +
scale_x_discrete("") +
scale_y_continuous("Number of Reads") +
scale_fill_discrete("Treatment") +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
ggplotly(p1)
Richness (Alpha diversity)
Shannon index (aka Shannon enthrophy) is calculated as:
H’ = -sum(1 to R)p(i)ln(p(i)) When there is exactly 1 type of data (e.g. a single species in the sample), H’=0. The opposite scenario is when there are R>1 species present in the sample in the exact same amounts and H’=ln(R).
Shannon’s diversity index was calculated for each sample and ploted over time using the 7,764 from the 13 Phylum above.
shannon.ndx <- estimate_richness(ps0,
measures = "Shannon")
shannon.ndx <- data.table(SAMPLE_NAME = rownames(shannon.ndx),
shannon.ndx)
smpl <- merge(smpl,
shannon.ndx,
by = "SAMPLE_NAME")
p1 <- ggplot(smpl,
aes(x = Total,
y = Shannon,
fill = Genotype,
shape = WEEK)) +
geom_point(size = 2) +
scale_shape_manual(breaks = unique(smpl$WEEK),
values = 21:23)
tiff(filename = "tmp/shannon_vs_depth.tiff",
height = 5,
width = 6,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
Even though estimate_richness function does not adjust for the sequencing depth, there is no correlation between the index and the sample’s sequecing depth. Proceed with the comparison.
Shannon idex over time
p1 <- plot_richness(ps0,
x = "time",
measures = "Shannon") +
facet_wrap(~ genotype) +
geom_line(aes(group = ID),
color = "black") +
geom_point(aes(fill = TREATMENT),
shape = 21,
size = 3,
color = "black") +
scale_x_discrete("") +
theme(axis.text.x = element_text(angle = 30,
hjust = 1,
vjust = 1))
ggplotly(p = p1,
tooltip = c("ID",
"value"))
p1 <- p1 +
scale_fill_discrete("") +
theme(legend.position = "top")
tiff(filename = "tmp/shannon.tiff",
height = 4,
width = 5,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
The plot above suggests that the largest differences in alpha diversity (as measured by Shannon’s index) are in genotype.
Test if the richness changed between the baseline and Week 8.
smpl$TREATMENT <- factor(smpl$TREATMENT,
levels = c("DSS",
"Naive",
"DSS+PEITC",
"DSS+Cranberry"))
tmp <- droplevels(smpl[WEEK != "week1"])
m1 <- lm(Shannon ~ WEEK*(TREATMENT + Genotype),
# offset = Total,
data = tmp)
summary(m1)
m2 <- lmer(Shannon ~ WEEK*(TREATMENT + Genotype) + (1 | ID),
# offset = Total,
data = tmp)
summary(m2)
Calculate change in Shannon index from baseline
dd <- smpl
dd[, delta := Shannon - Shannon[WEEK == "baseline"],
by = ID]
dd$diff <- paste(dd$WEEK,
"-baseline",
sep = "")
dd <- dd[WEEK != "baseline",]
p1 <- ggplot(dd,
aes(x = TREATMENT,
y = delta,
fill = Genotype)) +
facet_wrap(~ diff) +
geom_hline(yintercept = 0,
linetype = "dashed") +
geom_point(position = position_dodge(0.3),
shape = 21,
size = 3) +
scale_y_continuous("Shannon Index Percent Change from Baseline") +
theme(axis.text.x = element_text(angle = 45,
hjust = 1))
print(p1)

dd1$TREATMENT <- factor(dd1$TREATMENT,
levels = c("DSS",
"Naive",
"DSS+PEITC",
"DSS+Cranberry"))
dd1$Genotype <- factor(dd1$Genotype,
levels = c("widetype",
"nrf2KO"))
m1 <- lm(delta ~ TREATMENT*Genotype,
data = dd1)
summary(m1)
Call:
lm(formula = delta ~ TREATMENT * Genotype, data = dd1)
Residuals:
Min 1Q Median 3Q Max
-0.29055 -0.07985 -0.00783 0.08802 0.22709
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.269355 0.087465 3.080 0.00718 **
TREATMENTNaive 0.018571 0.123694 0.150 0.88253
TREATMENTDSS+PEITC -0.099962 0.123694 -0.808 0.43086
TREATMENTDSS+Cranberry 0.217339 0.123694 1.757 0.09802 .
Genotypenrf2KO -0.284714 0.123694 -2.302 0.03512 *
TREATMENTNaive:Genotypenrf2KO -0.013531 0.174930 -0.077 0.93930
TREATMENTDSS+PEITC:Genotypenrf2KO 0.232973 0.174930 1.332 0.20159
TREATMENTDSS+Cranberry:Genotypenrf2KO -0.003976 0.174930 -0.023 0.98215
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1515 on 16 degrees of freedom
Multiple R-squared: 0.6106, Adjusted R-squared: 0.4402
F-statistic: 3.584 on 7 and 16 DF, p-value: 0.01635
# No significant interactions, proceed with 2-way analysis
m2 <- lm(delta ~ TREATMENT + Genotype,
data = dd1)
summary(m2)
Call:
lm(formula = delta ~ TREATMENT + Genotype, data = dd1)
Residuals:
Min 1Q Median 3Q Max
-0.263616 -0.093216 0.000926 0.098885 0.196609
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 0.24242 0.06879 3.524 0.00227 **
TREATMENTNaive 0.01181 0.08701 0.136 0.89350
TREATMENTDSS+PEITC 0.01652 0.08701 0.190 0.85139
TREATMENTDSS+Cranberry 0.21535 0.08701 2.475 0.02291 *
Genotypenrf2KO -0.23085 0.06152 -3.752 0.00135 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.1507 on 19 degrees of freedom
Multiple R-squared: 0.5424, Adjusted R-squared: 0.446
F-statistic: 5.629 on 4 and 19 DF, p-value: 0.003664
At Week 8 there was significantly smaller increase of alpha diversity from baseline in Nrf2 KO compared to WT, and in DSS+Cranberry compared to DSS only.
Load aminoacids
aa <- fread("data_sep2019/sep2019_aminoacids.csv")
CONTINUE HERE! (2/11/2020)
The results showed that…
Remove unmapped OTUs
The 311 unmapped OTUs were removed from further analysis (with 7,247 OTUs left).
ps1 <- subset_taxa(ps0,
!is.na(Phylum))
dim(ps1@otu_table@.Data)
Counts at Phylum level
Relative abundance (%) at Phylum level
Remove phyla with relative abundance of >= 1% in less than 10% of samples.
t1 <- data.table(Phylum = ra_p$Phylum,
`Number of Samples` = rowSums(ra_p[, 2:ncol(ra_p)] >= 0.01))
t1$`Percent Samples` <- t1$`Number of Samples`/72
setorder(t1, -`Number of Samples`)
datatable(t1,
rownames = FALSE,
caption = "Taxonomic count table",
class = "cell-border stripe",
options = list(search = FALSE,
pageLength = nrow(t1))) %>%
formatPercentage(columns = 3,
digits = 1)
We will remove Chlamydiae from this analysis.
XX OTUs, down from YY OTUs in the previous table.
Relative Abundance in Samples at Different Taxonomic Ranks
1. Class
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Class,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_class_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu,
aes(x = x,
y = Class,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_class_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
2. Order
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
p0 <- ggplot(mu,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Order,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Order_over_time.tiff",
height = 5,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu,
aes(x = x,
y = Order,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Order_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
3. Family
NOTE: only the first 24 families had large enough counts - ploting only them.
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
mu1 <- droplevels(mu[Family %in% levels(mu$Family)[nlevels(mu$Family):(nlevels(mu$Family) - 24)], ])
p0 <- ggplot(mu1,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Family,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Family_over_time.tiff",
height = 7,
width = 9,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu1,
aes(x = x,
y = Family,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Family_ra.tiff",
height = 4,
width = 7,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
4. Genus
mu$Trt_Genotype <- factor(paste(mu$Treatment,
mu$Genotype,
sep = "_"))
mu1 <- droplevels(mu[Genus %in% levels(mu$Genus)[nlevels(mu$Genus):(nlevels(mu$Genus) - 35)], ])
p0 <- ggplot(mu1,
aes(x = Week,
y = x,
group = Trt_Genotype)) +
facet_wrap(~ Genus,
scale = "free_y") +
geom_line(position = position_dodge(0.3)) +
geom_point(aes(fill = Trt_Genotype),
shape = 21,
size = 2,
alpha = 0.5,
position = position_dodge(0.3)) +
scale_x_discrete("") +
scale_y_continuous("Relative Abundance (%)") +
theme(legend.position = "top",
axis.text.x = element_text(angle = 45,
hjust = 1))
tiff(filename = "tmp/wt_Genus_over_time.tiff",
height = 9,
width = 12,
units = "in",
res = 600,
compression = "lzw+p")
print(p0)
graphics.off()
print(p0)
p1 <- ggplot(mu1,
aes(x = x,
y = Genus,
color = Trt_Genotype,
shape = Week)) +
geom_point(size = 3,
alpha = 0.5) +
geom_vline(xintercept = 1,
linetype = "dashed") +
scale_x_continuous("Relative Abundance (%)") +
theme(legend.position = "top")
tiff(filename = "tmp/wt_Genus_ra.tiff",
height = 9,
width = 9,
units = "in",
res = 600,
compression = "lzw+p")
print(p1)
graphics.off()
ggplotly(p1)
LS0tCnRpdGxlOiAiRGF0YSBWaXN1YWxpemF0aW9uIG9mIFdUIGFuZCBOcmYyIEtPICgtLy0pIEJMNiBQRUlUQyBvciBDcmFuYmVycnkgVHJlYXRlZCBNaWNlIDE2UyBNaWNyb2Jpb21lIERhdGEgQW5hbHlzaXMsIFNlcHRlbWJlciAyMDE5IEJhdGNoIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCkRhdGU6IGByIGRhdGUoKWAgICAgIApTY2llbnRpc3Q6IFtSYW4gWWluXShtYWlsdG86cnkxNDdAc2NhcmxldG1haWwucnV0Z2Vycy5lZHUpICAgICAgClNlcXVlbmNpbmcgKFdha3NtYW4pOiBbRGlieWVuZHUgS3VtYXJdKG1haWx0bzpka0B3YWtzbWFuLnJ1dGdlcnMuZWR1KSAgICAgIApTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIApQcmluY2lwYWwgSW52ZXN0aWdhdG9yOiBbQWgtTmcgS29uZ10obWFpbHRvOmtvbmd0QHBoYXJtYWN5LnJ1dGdlcnMuZWR1KSAKCmBgYHt9CiMgVGF4b25vbWljIFJhbmtzOgojICoqSyoqaW5nICoqUCoqaGlsbGlwICoqQyoqYW4gbioqTyoqdCAqKkYqKmluZCAqKkcqKnJlZW4gKipTKipvY2tzCiMgKiBLaW5nZG9tICAgICAgICAgICAgICAgIAojICogUGh5bHVtICAgICAgICAgICAgICAgICAgICAKIyAqIENsYXNzICAgICAgICAgICAgICAgICAgIAojICogT3JkZXIgICAgICAgICAgICAgICAgICAgCiMgKiBGYW1pbHkgICAgIAojICogR2VudXMgICAgIAojICogU3BlY2llcyAgCmBgYAoKYGBge3Igc2V0dXB9CiMgb3B0aW9ucyhzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UsCiMgICAgICAgICBzY2lwZW4gPSA5OTkpCgojICMgSW5jcmVhc2UgbW1lbW9yeSBzaXplIHRvIDY0IEdiLS0tLQojIGludmlzaWJsZSh1dGlsczo6bWVtb3J5LmxpbWl0KDY1NTM2KSkKCgojIHN0cihrbml0cjo6b3B0c19jaHVuayRnZXQoKSkKIyAjIE5PVEU6IHRoZSBiZWxvdyBkb2VzIG5vdCB3b3JrIQojIGtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UsIAojICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gRkFMU0UsCiMgICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwKIyAgICAgICAgICAgICAgICAgICAgICAgZXJyb3IgPSBGQUxTRSkKCiMgcmVxdWlyZShrbml0cikKIyByZXF1aXJlKGthYmxlRXh0cmEpCnJlcXVpcmUocGh5bG9zZXEpCiMgcmVxdWlyZShzaGlueSkKCnJlcXVpcmUoZGF0YS50YWJsZSkKcmVxdWlyZShnZ3Bsb3QyKQpyZXF1aXJlKHBsb3RseSkKcmVxdWlyZShEVCkKcmVxdWlyZShsbWVyVGVzdCkKCnNvdXJjZSgic291cmNlL2Z1bmN0aW9uc19tYXkyMDE5LlIiKQoKIyBPbiBXaW5kb3dzIHNldCBtdWx0aXRocmVhZD1GQUxTRS0tLS0KbXQgPC0gVFJVRQpgYGAKCiMgSW50cm9kdWN0aW9uCkM1N0JMLzYgd2lsZC10eXBlIChXVCkgYW5kIE5yZi0yIGRvdWJsZS1rbm9jay1vdXQgKEtPIC0vLSkgbWljZSB3ZXJlIGdpdmVuIDItd2VlayBtaWNyb2Jpb21lIHN0YWJpbGl6YXRpb24gcHJvY2VzcyB1c2luZyBBSU45M00gZGlldCBhbmQgOCBtb3JlIHdlZWtzIHRvIHRyZWF0IHdpdGggZWl0aGVyIEFJTjkzTSBvciBBSU45M00gNSUgUEVJVEMgZGlldC4gRmVjYWwgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCB3ZWVrbHksIGltbWVkaWF0ZWx5IGZyb3plbiBpbiBsaXF1aWQgbml0cm9nZW4gYW5kIHN0b3JlZCBhdCAtODBeb15DLiBTZXJ1bSwgY2VjYWwsIGNvbG9uIGVwaXRoZWxpYWwgYW5kIHdob2xlIGNvbG9uIHRpc3N1ZXMgYXQgd2VlayAxMCB3ZXJlIGFsc28gY29sbGVjdGVkIGZvciBmdXJ0aGVyIGFuYWx5c2VzLiBCYXNlbGluZSwgd2VlayAxIGFuZCA0IGZlY2FsIHNhbXBsZXMgd2VyZSBzZWxlY3RlZCBmb3IgMTZzIHJSTkEgc2VxdWVuY2luZy4gIAogIApUaGlzIGRvY3VtZW50IGV4YW1pbmVzIHJlc3VsdHMgZnJvbSB0aGUgV1QgbWljZSBzYW1wbGVzLiAgCiAgCldlIHdpbGwgYXR0YW1wdCB0byBhbnN3ZXIgdGhlIGZvbGxvd2luZyBxdWVzdGlvbnM6ICAKMS4gRGlkIG1pY3JvYmlvbWUgY2hhbmdlIG92ZXIgdGltZT8gIAoyLiBXYXMgbWljcm9iaW9tZSBhZmZlY3RlZCBieSBkaWV0PyAgCjMuIFdhcyB0aGVyZSBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgS08gYW5kIFdUPyAgCjQuIElmIHRoZXJlIHdhcyBhIGNoYW5nZSBpbiBtaWNyb2Jpb21lIGNvbXBvc2l0aW9uLCB3aGF0IGZ1bmN0aW9uYWwgY2hhbmdlcyBkaWQgaXQgY2Fycnk/IFdoYXQgYXJlIHRoZSBlc3NlbnRpYWwgZnVuY3Rpb25zIG9mIHRoZSBiYWN0ZXJpYSBhZmZlY3RlZCBieSB0aGUgdHJlYXRtZW50IGFuZCBob3cgY2FuIHRoaXMgYmUgc2hvd24gaW4gdml2byAobWV0YWJvbGl0ZXMsIGluZmxhbW1hdGlvbiBtYXJrZXJzLCBldGMuKT8KCiMgRGF0YSBwcmVwcm9jZXNzaW5nCiMjIFJhdyBEYXRhIApGYXN0USBmaWxlcyB3ZXJlIGRvd25sb2FkZWQgZnJvbSBbdGhpcyBSdXRnZXJzIEJveCBsb2NhdGlvbl0oaHR0cHM6Ly9ydXRnZXJzLmFwcC5ib3guY29tL2ZvbGRlci85MDE0MzQ2MjI5MSkuIEEgdG90YWwgb2YgMTQ0IGZpbGVzICgyIHBlciBzYW1wbGUsIHBhaXItZW5kZWQpIGFuZCBhIHBhaXIgb2YgdW5kZXRlcm1pbmVkIHJlYWRzIHdlcmUgZG93bmxvYWRlZC4gCgojIyBTY3JpcHQKVGhpcyBzY3JpcHQgKCoqKm5yZjJ1YmlvbWVfZGFkYTJfc2VwMjAxOV92MS5SbWQqKiopIHdhcyBkZXZlbG9wZWQgdXNpbmcgW0RBREEyIFBpcGVsaW5lIFR1dG9yaWFsICgxLjEyKV0oaHR0cHM6Ly9iZW5qam5lYi5naXRodWIuaW8vZGFkYTIvdHV0b3JpYWwuaHRtbCkgd2l0aCB0aXBzIGFuZCB0cmlja3MgZnJvbSB0aGUgW1VuaXZlcnNpdHkgb2YgTWFyeWxhbmQgU2hvb2wgb2YgTWVkaWNpbmUgSW5zdGl0dXRlIGZvciBHZW5vbWUgU2NpZW5jZXMgKElHUyldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvKSBbTWljcm9iaW9tZSBBbmFseXNpcyBXb3Jrc2hvcCAoQXByaWwgOC0xMSwgMjAxOSldKGh0dHA6Ly93d3cuaWdzLnVtYXJ5bGFuZC5lZHUvZWR1Y2F0aW9uL3drc2hwX21ldGFnZW5vbWUucGhwKS4gVGhlIG91dHB1dCBvZiB0aGUgREFEQTIgc2NyaXB0ICgqKipkYXRhX21heTIwMTkvcHNfc2VwMjAxOS5SRGF0YSoqKikgaXMgZXhwbG9yZWQgaW4gdGhpcyBkb2N1bWVudC4KCiMgTWV0YSBkYXRhOiBzYW1wbGUgZGVzY3JpcHRpb24KYGBge3IgZGF0YX0KIyBMb2FkIGRhdGEtLS0tCiMgQ291bnRzCmxvYWQoImRhdGFfc2VwMjAxOS9wc19zZXAyMDE5LlJEYXRhIikKCiMgVGF4b25vbXkKbG9hZCgiZGF0YV9zZXAyMDE5L3RheGEuUkRhdGEiKQp0YXhhIDwtIGRhdGEudGFibGUoc2VxMTZzID0gcm93bmFtZXModGF4YSksCiAgICAgICAgICAgICAgICAgICB0YXhhKQpgYGAKCioqTk9URTogY29ycmVjdGlvbiB0byB0aGUgbWV0YS1kYXRhISoqICgxMS8xNS8yMDE5KQpgYGB7ciBjb3JyZWN0X21ldGFfZGF0YX0KY29ycmVjdF9zYW1wbGVzIDwtIGZyZWFkKCJkYXRhX3NlcDIwMTkvMTZzIG1ldGFkYXRhIFNlcC0yMDE5LmNzdiIpCnBzX3NlcDIwMTlAc2FtX2RhdGEkRFNTIDwtIGNvcnJlY3Rfc2FtcGxlcyREU1MKYGBgCgojIFNhbXBsZXMKYGBge3Igc2FtcGxlc30KcHNfc2VwMjAxOUBzYW1fZGF0YSRHZW5vdHlwZV9XZWVrIDwtIHBhc3RlKHBzX3NlcDIwMTlAc2FtX2RhdGEkZ2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJHRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpCnBzX3NlcDIwMTlAc2FtX2RhdGEkSUQgPC0gZmFjdG9yKHBhc3RlMChwc19zZXAyMDE5QHNhbV9kYXRhJG1pY2VfbnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHNfc2VwMjAxOUBzYW1fZGF0YSRjYWdlKSkKCnBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5UIDwtIHBhc3RlMChwc19zZXAyMDE5QHNhbV9kYXRhJERTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBzX3NlcDIwMTlAc2FtX2RhdGEkUEVJVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwc19zZXAyMDE5QHNhbV9kYXRhJGNyYW5iZXJyeSkKcHNfc2VwMjAxOUBzYW1fZGF0YSRUUkVBVE1FTlQgPC0gZmFjdG9yKHBzX3NlcDIwMTlAc2FtX2RhdGEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiMDAwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjEwMCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIxMTAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiMTAxIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJOYWl2ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEU1MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkKCnNhbXBsZXMgPC0gcHNfc2VwMjAxOUBzYW1fZGF0YQpkYXRhdGFibGUoc2FtcGxlcywKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSBucm93KHNhbXBsZXMpKSkKYGBgCgojIFBydW5lIGRhdGEKVGhlIE9UVXMgd2VyZSBtYXBwZWQgdG8gQmFjdGVyaWEgKDk2LjA3JSksIEV1a2FyeW90YSAoMi45NSUpIGFuZCBBcmNoZWEgKDAuMDMlKSBraW5nZG9tcywgYW5kICA3NSBPVFVzICgwLjk1JSkgdW5kZWZpbmVkLiAKCmBgYHtyIGNoZWNrX21hcHBpbmdfa2luZ2RvbSwgd2FybmluZyA9IEZBTFNFLCBlY2hvID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KdDEgPC0gZGF0YS50YWJsZSh0YWJsZSh0YXhfdGFibGUocHNfc2VwMjAxOSlbLCAiS2luZ2RvbSJdLAogICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkKdDEkVjFbaXMubmEodDEkVjEpXSA8LSAiVW5rbm93biIKCnQxWywgcGN0IDo9IE4vc3VtKE4pXQpzZXRvcmRlcih0MSwgLU4pCgpjb2xuYW1lcyh0MSkgPC0gYygiS2luZ2RvbSIsCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsCiAgICAgICAgICAgICAgICAgICJQZXJjZW50IG9mIE9UVXMiKQpkYXRhdGFibGUodDEsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJOdW1iZXIgb2YgT1RVcyBieSBLaW5nZG9tIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQogIGZvcm1hdEN1cnJlbmN5KGNvbHVtbnMgPSAyLAogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwKICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKSAlPiUKICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAzLAogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpUaGUgdG90YWwgb2YgNyw4NjcgdW5pcXVlIHNlcXVlbmNlcyB3ZXJlIGZvdW5kLiBPdXQgb2YgdGhvc2UsIDcsNTU4IHdlcmUgbWFwcGVkIHRvIGJhY3RlcmlhbCBnZW5vbWVzLiAKCmBgYHtyIGtlZXBfYmFjdGVyaWF9CmRpbShwc19zZXAyMDE5QG90dV90YWJsZUAuRGF0YSkKCiMgUmVtb3ZlIE9UVSBub3QgbWFwcGVkIHRvIEJhY3RlcmlhCnBzMCA8LSBzdWJzZXRfdGF4YShwc19zZXAyMDE5LCAKICAgICAgICAgICAgICAgICAgIEtpbmdkb20gPT0gIkJhY3RlcmlhIikKZGltKHBzMEBvdHVfdGFibGVALkRhdGEpCmBgYAogIApPdXQgb2YgdGhlIDcsNTU4IE9UVXMgNywyNDcgYmVsb25nZWQgdG8gMTIgUGh5bGEuIDMxMSBvZiB0aGUgT1RVcyAob3IgNC4xMSUgb2YgYmFjdGVyaWFsIE9UVXMpIGNvdWxkIG5vdCBiZSBtYXBwZWQgdG8gYSBwaHlsdW0uCgpgYGB7ciBwaHlsdW1fbWFwcGluZ30KdDIgPC0gZGF0YS50YWJsZSh0YWJsZSh0YXhfdGFibGUocHMwKVssICJQaHlsdW0iXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGUgPSBOVUxMKSkKdDIkVjFbaXMubmEodDIkVjEpXSA8LSAiVW5rbm93biIKc2V0b3JkZXIodDIsIC1OKQp0MlssIHBjdCA6PSBOL3N1bShOKV0Kc2V0b3JkZXIodDIsIC1OKQoKY29sbmFtZXModDIpIDwtIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICJOdW1iZXIgb2YgT1RVcyIsCiAgICAgICAgICAgICAgICAgICJQZXJjZW50IG9mIE9UVXMiKQoKZGF0YXRhYmxlKHQyLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiTnVtYmVyIG9mIEJhY3RlcmlhbCBPVFVzIGJ5IFBoeWx1bSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gbnJvdyh0MikpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gMiwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkgJT4lCiAgZm9ybWF0UGVyY2VudGFnZShjb2x1bW5zID0gMywKICAgICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKIyBPVFUgdGFibGUgKGZpcnN0IDEwIHJvd3MpCmBgYHtyIG90dV90YWJsZSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9Cm90dSA8LSBkYXRhLnRhYmxlKHBzMEB0YXhfdGFibGVALkRhdGEsCiAgICAgICAgICAgICAgICAgIHQocHMwQG90dV90YWJsZUAuRGF0YSkpCmRhdGF0YWJsZShoZWFkKG90dSwgMTApLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNzozNiwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMCkKYGBgCgojIFRvdGFsIGNvdW50cyBwZXIgc2FtcGxlIChpLmUuIHNlcXVlbmNpbmcgZGVwdGgpCmBgYHtyIHNlcV9kZXB0aCwgZmlnLndpZHRoID0gMTAsZmlnLmhlaWdodCA9IDV9CnQxIDwtIGNvbFN1bXMob3R1WywgNzpuY29sKG90dSldKQp0MSA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gbmFtZXModDEpLAogICAgICAgICAgICAgICAgIFRvdGFsID0gdDEpCgp0MiA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gcm93bmFtZXMoc2FtcGxlcyksCiAgICAgICAgICAgICAgICAgSUQgPSBzYW1wbGVzJElELAogICAgICAgICAgICAgICAgIENBR0UgPSBzYW1wbGVzJGNhZ2UsCiAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc2FtcGxlcyRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBzYW1wbGVzJGdlbm90eXBlLAogICAgICAgICAgICAgICAgIFdFRUsgPSBzYW1wbGVzJHRpbWUpCgpzbXBsIDwtIG1lcmdlKHQxLAogICAgICAgICAgICAgIHQyLAogICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCnAxIDwtIGdncGxvdChzbXBsLAogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICB5ID0gVG90YWwsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICBjb2xvdXIgPSBXRUVLKSkgKwogIGZhY2V0X3dyYXAofiBHZW5vdHlwZSwKICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeCIpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIk51bWJlciBvZiBSZWFkcyIpICsKICBzY2FsZV9maWxsX2Rpc2NyZXRlKCJUcmVhdG1lbnQiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKSAKZ2dwbG90bHkocDEpCmBgYAoKIyBSaWNobmVzcyAoQWxwaGEgZGl2ZXJzaXR5KQpTaGFubm9uIGluZGV4IChha2EgU2hhbm5vbiBlbnRocm9waHkpIGlzIGNhbGN1bGF0ZWQgYXM6ICAKSCcgPSAtc3VtKDEgdG8gUilwKGkpbG4ocChpKSkgCldoZW4gdGhlcmUgaXMgZXhhY3RseSAxIHR5cGUgb2YgZGF0YSAoZS5nLiBhIHNpbmdsZSBzcGVjaWVzIGluIHRoZSBzYW1wbGUpLCBIJz0wLiBUaGUgb3Bwb3NpdGUgc2NlbmFyaW8gaXMgd2hlbiB0aGVyZSBhcmUgUj4xIHNwZWNpZXMgcHJlc2VudCBpbiB0aGUgc2FtcGxlIGluIHRoZSBleGFjdCBzYW1lIGFtb3VudHMgYW5kIEgnPWxuKFIpLiAgCiAgClNoYW5ub24ncyBkaXZlcnNpdHkgaW5kZXggd2FzIGNhbGN1bGF0ZWQgZm9yIGVhY2ggc2FtcGxlIGFuZCBwbG90ZWQgb3ZlciB0aW1lIHVzaW5nIHRoZSA3LDc2NCBmcm9tIHRoZSAxMyBQaHlsdW0gYWJvdmUuCiAgCmBgYHtyIHNoYW5ub25fdnNfZGVwdGgsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA2fQpzaGFubm9uLm5keCA8LSBlc3RpbWF0ZV9yaWNobmVzcyhwczAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKQoKc2hhbm5vbi5uZHggPC0gZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHJvd25hbWVzKHNoYW5ub24ubmR4KSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFubm9uLm5keCkKCnNtcGwgPC0gbWVyZ2Uoc21wbCwKICAgICAgICAgICAgICBzaGFubm9uLm5keCwKICAgICAgICAgICAgICBieSA9ICJTQU1QTEVfTkFNRSIpCgpwMSA8LSBnZ3Bsb3Qoc21wbCwKICAgICAgICAgICAgIGFlcyh4ID0gVG90YWwsCiAgICAgICAgICAgICAgICAgeSA9IFNoYW5ub24sCiAgICAgICAgICAgICAgICAgZmlsbCA9IEdlbm90eXBlLAogICAgICAgICAgICAgICAgIHNoYXBlID0gV0VFSykpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgc2NhbGVfc2hhcGVfbWFudWFsKGJyZWFrcyA9IHVuaXF1ZShzbXBsJFdFRUspLAogICAgICAgICAgICAgICAgICAgICB2YWx1ZXMgPSAyMToyMykKCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub25fdnNfZGVwdGgudGlmZiIsCiAgICAgaGVpZ2h0ID0gNSwKICAgICB3aWR0aCA9IDYsCiAgICAgdW5pdHMgPSAiaW4iLAogICAgIHJlcyA9IDYwMCwKICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpCnByaW50KHAxKQpncmFwaGljcy5vZmYoKQoKZ2dwbG90bHkocDEpCmBgYAoKRXZlbiB0aG91Z2ggKioqZXN0aW1hdGVfcmljaG5lc3MqKiogZnVuY3Rpb24gZG9lcyBub3QgYWRqdXN0IGZvciB0aGUgc2VxdWVuY2luZyBkZXB0aCwgdGhlcmUgaXMgbm8gY29ycmVsYXRpb24gYmV0d2VlbiB0aGUgaW5kZXggYW5kIHRoZSBzYW1wbGUncyBzZXF1ZWNpbmcgZGVwdGguIFByb2NlZWQgd2l0aCB0aGUgY29tcGFyaXNvbi4KCiMgU2hhbm5vbiBpZGV4IG92ZXIgdGltZQpgYGB7ciByaWNobmVzcywgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodCA9IDV9CnAxIDwtIHBsb3RfcmljaG5lc3MocHMwLAogICAgICAgICAgICAgICAgICAgIHggPSAidGltZSIsIAogICAgICAgICAgICAgICAgICAgIG1lYXN1cmVzID0gIlNoYW5ub24iKSArCiAgZmFjZXRfd3JhcCh+IGdlbm90eXBlKSArCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IElEKSwKICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRSRUFUTUVOVCksCiAgICAgICAgICAgICBzaGFwZSA9IDIxLAogICAgICAgICAgICAgc2l6ZSA9IDMsCiAgICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmp1c3QgPSAxKSkKCmdncGxvdGx5KHAgPSBwMSwKICAgICAgICAgdG9vbHRpcCA9IGMoIklEIiwKICAgICAgICAgICAgICAgICAgICAgInZhbHVlIikpCgpwMSA8LSBwMSArIAogIHNjYWxlX2ZpbGxfZGlzY3JldGUoIiIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikKCnRpZmYoZmlsZW5hbWUgPSAidG1wL3NoYW5ub24udGlmZiIsCiAgICAgaGVpZ2h0ID0gNCwKICAgICB3aWR0aCA9IDUsCiAgICAgdW5pdHMgPSAiaW4iLAogICAgIHJlcyA9IDYwMCwKICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpCnByaW50KHAxKQpncmFwaGljcy5vZmYoKQpgYGAKClRoZSBwbG90IGFib3ZlIHN1Z2dlc3RzIHRoYXQgdGhlIGxhcmdlc3QgZGlmZmVyZW5jZXMgaW4gYWxwaGEgZGl2ZXJzaXR5IChhcyBtZWFzdXJlZCBieSBTaGFubm9uJ3MgaW5kZXgpIGFyZSBpbiBnZW5vdHlwZS4KICAKVGVzdCBpZiB0aGUgcmljaG5lc3MgY2hhbmdlZCBiZXR3ZWVuIHRoZSBiYXNlbGluZSBhbmQgV2VlayA4LiAgCiAgCmBgYHtyIGxtX3JpY2huZXNzfQpzbXBsJFRSRUFUTUVOVCA8LSBmYWN0b3Ioc21wbCRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJEU1MiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTmFpdmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRTUytDcmFuYmVycnkiKSkKCnRtcCA8LSBkcm9wbGV2ZWxzKHNtcGxbV0VFSyAhPSAid2VlazEiXSkKCm0xIDwtIGxtKFNoYW5ub24gIH4gV0VFSyooVFJFQVRNRU5UICsgR2Vub3R5cGUpLAogICAgICAgICAjIG9mZnNldCA9IFRvdGFsLAogICAgICAgICBkYXRhID0gdG1wKQpzdW1tYXJ5KG0xKQpgYGAKICAKYGBge3IgbG1lcl9yaWNobmVzc30KbTIgPC0gbG1lcihTaGFubm9uICB+IFdFRUsqKFRSRUFUTUVOVCArIEdlbm90eXBlKSArICgxIHwgSUQpLAogICAgICAgICAgICMgb2Zmc2V0ID0gVG90YWwsCiAgICAgICAgICAgZGF0YSA9IHRtcCkKc3VtbWFyeShtMikKYGBgCgojIENhbGN1bGF0ZSBjaGFuZ2UgaW4gU2hhbm5vbiBpbmRleCBmcm9tIGJhc2VsaW5lCmBgYHtyIGRlbHRhX3NoYW5ub24sIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA1fQpkZCA8LSBzbXBsCmRkWywgZGVsdGEgOj0gU2hhbm5vbiAtIFNoYW5ub25bV0VFSyA9PSAiYmFzZWxpbmUiXSwKICAgYnkgPSBJRF0KZGQkZGlmZiA8LSBwYXN0ZShkZCRXRUVLLAogICAgICAgICAgICAgICAgICItYmFzZWxpbmUiLAogICAgICAgICAgICAgICAgIHNlcCA9ICIiKQoKZGQgPC0gZGRbV0VFSyAhPSAiYmFzZWxpbmUiLF0KCnAxIDwtIGdncGxvdChkZCwKICAgICAgICAgICAgIGFlcyh4ID0gVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgIHkgPSBkZWx0YSwKICAgICAgICAgICAgICAgICBmaWxsID0gR2Vub3R5cGUpKSArCiAgZmFjZXRfd3JhcCh+IGRpZmYpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLAogICAgICAgICAgICAgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpLAogICAgICAgICAgICAgc2hhcGUgPSAyMSwKICAgICAgICAgICAgIHNpemUgPSAzKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJTaGFubm9uIEluZGV4IFBlcmNlbnQgQ2hhbmdlIGZyb20gQmFzZWxpbmUiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQpwcmludChwMSkKCmRkMSRUUkVBVE1FTlQgPC0gZmFjdG9yKGRkMSRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIkRTUyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk5haXZlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK1BFSVRDIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRFNTK0NyYW5iZXJyeSIpKQpkZDEkR2Vub3R5cGUgPC0gZmFjdG9yKGRkMSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSBjKCJ3aWRldHlwZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibnJmMktPIikpCgptMSA8LSBsbShkZWx0YSB+IFRSRUFUTUVOVCpHZW5vdHlwZSwKICAgICAgICAgZGF0YSA9IGRkMSkKc3VtbWFyeShtMSkKCiMgTm8gc2lnbmlmaWNhbnQgaW50ZXJhY3Rpb25zLCBwcm9jZWVkIHdpdGggMi13YXkgYW5hbHlzaXMKbTIgPC0gbG0oZGVsdGEgfiBUUkVBVE1FTlQgKyBHZW5vdHlwZSwKICAgICAgICAgZGF0YSA9IGRkMSkKc3VtbWFyeShtMikKYGBgCgpBdCBXZWVrIDggdGhlcmUgd2FzIHNpZ25pZmljYW50bHkgc21hbGxlciBpbmNyZWFzZSBvZiBhbHBoYSBkaXZlcnNpdHkgZnJvbSBiYXNlbGluZSBpbiBOcmYyIEtPIGNvbXBhcmVkIHRvIFdULCBhbmQgaW4gRFNTK0NyYW5iZXJyeSBjb21wYXJlZCB0byBEU1Mgb25seS4KCiMgTG9hZCBhbWlub2FjaWRzCmBgYHtyIGFtaW5vYWNpZHN9CmFhIDwtIGZyZWFkKCJkYXRhX3NlcDIwMTkvc2VwMjAxOV9hbWlub2FjaWRzLmNzdiIpCmBgYAoKCgpDT05USU5VRSBIRVJFISAoMi8xMS8yMDIwKQoKVGhlIHJlc3VsdHMgc2hvd2VkIHRoYXQuLi4KCgoKCgoKCiMgUmVtb3ZlIHVubWFwcGVkIE9UVXMKVGhlIDMxMSB1bm1hcHBlZCBPVFVzIHdlcmUgcmVtb3ZlZCBmcm9tIGZ1cnRoZXIgYW5hbHlzaXMgKHdpdGggNywyNDcgT1RVcyBsZWZ0KS4KYGBge3IgcmVtb3ZlX3VubWFwcGVkX290dV9waHlsdW19CnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIAogICAgICAgICAgICAgICAgICAgIWlzLm5hKFBoeWx1bSkpCmRpbShwczFAb3R1X3RhYmxlQC5EYXRhKQpgYGAKCiMgQ291bnRzIGF0IFBoeWx1bSBsZXZlbApgYGB7ciBjb3VudHNfcCwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmNvdW50c19wIDwtIGNvdW50c19ieV90YXhfcmFuayhkdDEgPSBvdHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dyX2J5ID0gIlBoeWx1bSIpCnNldG9yZGVyKGNvdW50c19wLCAtYDE5MDkxOS0wMWApCmRhdGF0YWJsZShjb3VudHNfcCwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3coY291bnRzX3ApKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDI6bmNvbChjb3VudHNfcCksCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDApCmBgYAoKIyBSZWxhdGl2ZSBhYnVuZGFuY2UgKCUpIGF0IFBoeWx1bSBsZXZlbApgYGB7ciByYV9wLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KcmFfcCA8LSByYV9ieV90YXhfcmFuayhjb3VudHMgPSBjb3VudHNfcCwKICAgICAgICAgICAgICAgICAgICAgICBwY3QgPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBkaWdpdCA9IDQpCgpkYXRhdGFibGUocmFfcCwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IG5yb3cocmFfcCkpKSAlPiUKICBmb3JtYXRQZXJjZW50YWdlKGNvbHVtbnMgPSAyOm5jb2woY291bnRzX3ApLAogICAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpSZW1vdmUgcGh5bGEgd2l0aCByZWxhdGl2ZSBhYnVuZGFuY2Ugb2YgPj0gMSUgaW4gbGVzcyB0aGFuIDEwJSBvZiBzYW1wbGVzLgoKYGBge3IgcHJldl9wfQp0MSA8LSBkYXRhLnRhYmxlKFBoeWx1bSA9IHJhX3AkUGh5bHVtLAogICAgICAgICAgICAgICAgIGBOdW1iZXIgb2YgU2FtcGxlc2AgPSByb3dTdW1zKHJhX3BbLCAyOm5jb2wocmFfcCldID49IDAuMDEpKQp0MSRgUGVyY2VudCBTYW1wbGVzYCA8LSAgdDEkYE51bWJlciBvZiBTYW1wbGVzYC83MgoKc2V0b3JkZXIodDEsIC1gTnVtYmVyIG9mIFNhbXBsZXNgKQpkYXRhdGFibGUodDEsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSBucm93KHQxKSkpICU+JQogIGZvcm1hdFBlcmNlbnRhZ2UoY29sdW1ucyA9IDMsCiAgICAgICAgICAgICAgICAgICBkaWdpdHMgPSAxKQpgYGAKCldlIHdpbGwgcmVtb3ZlIENobGFteWRpYWUgZnJvbSB0aGlzIGFuYWx5c2lzLgoKYGBge3Iga2VlcF82X3BoeWxhLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0Ka2VlcF9wIDwtIHQxJFBoeWx1bVt0MSRgUGVyY2VudCBTYW1wbGVzYCA+PSAwLjFdCiMgIyBLZWVwIGFsbAojIGtlZXBfcCA8LSB0MSRQaHlsdW0KCnBhc3RlMChrZWVwX3AsIGNvbGxhcHNlID0gIiwgIikKCnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIAogICAgICAgICAgICAgICAgICAgUGh5bHVtICVpbiUga2VlcF9wICkKb3R1MSA8LSBkYXRhLnRhYmxlKHBzMUB0YXhfdGFibGVALkRhdGEsCiAgICAgICAgICAgICAgICAgICB0KHBzMUBvdHVfdGFibGVALkRhdGEpKQoKZGF0YXRhYmxlKGhlYWQob3R1MSwgMTApLAogICAgICAgICAgcm93bmFtZXMgPSBGQUxTRSwKICAgICAgICAgIGNhcHRpb24gPSAiVGF4b25vbWljICBjb3VudCB0YWJsZSIsCiAgICAgICAgICBjbGFzcyA9ICJjZWxsLWJvcmRlciBzdHJpcGUiLAogICAgICAgICAgb3B0aW9ucyA9IGxpc3Qoc2VhcmNoID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICAgICBwYWdlTGVuZ3RoID0gMTApKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNzpuY29sKG90dTEpLAogICAgICAgICAgICAgICAgIGN1cnJlbmN5ID0gIiIsCiAgICAgICAgICAgICAgICAgbWFyayA9ICIsIiwKICAgICAgICAgICAgICAgICBkaWdpdHMgPSAwKQpgYGAKClhYIE9UVXMsIGRvd24gZnJvbSBZWSBPVFVzIGluIHRoZSBwcmV2aW91cyB0YWJsZS4KCgojIFJlbGF0aXZlIEFidW5kYW5jZSBpbiBTYW1wbGVzIGF0IERpZmZlcmVudCBUYXhvbm9taWMgUmFua3MKIyMgMS4gQ2xhc3MKYGBge3IgY291bnRzX2MsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQpjb3VudHNfYyA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiQ2xhc3MiKQpyYV9jIDwtIHJhX2J5X3RheF9yYW5rKGNvdW50c19jKQoKdGF4LnJhbmtzIDwtIHVuaXF1ZShvdHUxWywgYygiUGh5bHVtIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ2xhc3MiKV0pCgpyYV9jIDwtIG1lcmdlKHRheC5yYW5rcywKICAgICAgICAgICAgICByYV9jLAogICAgICAgICAgICAgIGJ5ID0gIkNsYXNzIikKCnRvdGFsIDwtIHJvd1N1bXMocmFfY1ssIDM6bmNvbChyYV9jKV0pCgpyYV9jJENsYXNzIDwtIGZhY3RvcihyYV9jJENsYXNzLAogICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSByYV9jJENsYXNzW29yZGVyKHRvdGFsKV0pCgpyYV9jJFBoeWx1bSA8LSBmYWN0b3IocmFfYyRQaHlsdW0sCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfYyRQaHlsdW1bb3JkZXIodG90YWwpXSkpCnRtcCA8LSBtZWx0LmRhdGEudGFibGUoZGF0YSA9IHJhX2MsCiAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IDE6MiwKICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2MpLAogICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU0FNUExFX05BTUUiLAogICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiUkEiKQoKdG1wIDwtIG1lcmdlKGRhdGEudGFibGUoU0FNUExFX05BTUUgPSBzbXBsJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICBXRUVLID0gc21wbCRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBzbXBsJEdlbm90eXBlKSwKICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCiMgUGxvdCBzYW1wbGVzCnAxIDwtIGdncGxvdCh0bXAsCiAgICAgICAgICAgICBhZXMoeCA9IFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgIHkgPSBSQSwKICAgICAgICAgICAgICAgICBmaWxsID0gQ2xhc3MsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBQaHlsdW0pKSArCiAgZmFjZXRfd3JhcCh+IFdFRUsgKyBUUkVBVE1FTlQgKyBHZW5vdHlwZSwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbnJvdyA9IDMpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQpnZ3Bsb3RseShwMSkKYGBgCgpgYGB7ciBtZWFuc19jLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2MsCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzbXBsLAogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpCgptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBscmEkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyA9IGxyYSRDbGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9ICJtZWFuIikpCm11WywgdG90YWwgOj0gc3VtKHgpLAogICBieSA9ICJDbGFzcyJdCnVsIDwtIHVuaXF1ZShtdVssIGMoIkNsYXNzIiwgCiAgICAgICAgICAgICAgICAgICAgInRvdGFsIildKQp1bCA8LSB1bFtvcmRlcih0b3RhbCksXQptdSRDbGFzcyA8LSBmYWN0b3IobXUkQ2xhc3MsCiAgICAgICAgICAgICAgICAgICBsZXZlbCA9IHVsJENsYXNzKQptdSR0b3RhbCA8LSBOVUxMCgpkYXRhdGFibGUobXUsCiAgICAgICAgICByb3duYW1lcyA9IEZBTFNFLAogICAgICAgICAgY2FwdGlvbiA9ICJUYXhvbm9taWMgIGNvdW50IHRhYmxlIiwKICAgICAgICAgIGNsYXNzID0gImNlbGwtYm9yZGVyIHN0cmlwZSIsCiAgICAgICAgICBvcHRpb25zID0gbGlzdChzZWFyY2ggPSBGQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VMZW5ndGggPSAxMCwKICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKCmBgYHtyIG1lYW5zX2NfcDAsIGZpZy53aWR0aCA9IDksIGZpZy5oZWlnaHQgPSA3fQptdSRUcnRfR2Vub3R5cGUgPC0gZmFjdG9yKHBhc3RlKG11JFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICBtdSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpKQoKcDAgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSBXZWVrLAogICAgICAgICAgICAgICAgIHkgPSB4LAogICAgICAgICAgICAgICAgIGdyb3VwID0gVHJ0X0dlbm90eXBlKSkgKwogIGZhY2V0X3dyYXAofiBDbGFzcywKICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsKICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksCiAgICAgICAgICAgICBzaGFwZSA9IDIxLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfY2xhc3Nfb3Zlcl90aW1lLnRpZmYiLAogICAgIGhlaWdodCA9IDUsCiAgICAgd2lkdGggPSA3LAogICAgIHVuaXRzID0gImluIiwKICAgICByZXMgPSA2MDAsCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQpwcmludChwMCkKZ3JhcGhpY3Mub2ZmKCkKCnByaW50KHAwKQpgYGAKCgpgYGB7ciBtZWFuc19jX3AxLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gOX0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBDbGFzcywKICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9jbGFzc19yYS50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCgpnZ3Bsb3RseShwMSkKYGBgCgojIyAyLiBPcmRlcgpgYGB7ciBjb3VudHNfbywgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTE1LGZpZy5oZWlnaHQ9MTV9CmNvdW50c19vIDwtIGNvdW50c19ieV90YXhfcmFuayhkdDEgPSBvdHUxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJPcmRlciIpCnJhX28gPC0gcmFfYnlfdGF4X3JhbmsoY291bnRzX28pCgp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPcmRlciIpXSkKCnJhX28gPC0gbWVyZ2UodGF4LnJhbmtzLAogICAgICAgICAgICAgIHJhX28sCiAgICAgICAgICAgICAgYnkgPSAiT3JkZXIiKQoKdG90YWwgPC0gcm93U3VtcyhyYV9vWywgMzpuY29sKHJhX28pXSkKCnJhX28kT3JkZXIgPC0gZmFjdG9yKHJhX28kT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX28kT3JkZXJbb3JkZXIodG90YWwpXSkKCnJhX28kUGh5bHVtIDwtIGZhY3RvcihyYV9vJFBoeWx1bSwKICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHVuaXF1ZShyYV9vJFBoeWx1bVtvcmRlcih0b3RhbCldKSkKdG1wIDwtIG1lbHQuZGF0YS50YWJsZShkYXRhID0gcmFfbywKICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLAogICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IDM6bmNvbChjb3VudHNfbyksCiAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJTQU1QTEVfTkFNRSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpCgp0bXAgPC0gbWVyZ2UoZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHNtcGwkU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzbXBsJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNtcGwkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IHNtcGwkR2Vub3R5cGUpLAogICAgICAgICAgICAgdG1wLAogICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKIyBQbG90IHNhbXBsZXMKcDEgPC0gZ2dwbG90KHRtcCwKICAgICAgICAgICAgIGFlcyh4ID0gU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgeSA9IFJBLAogICAgICAgICAgICAgICAgIGZpbGwgPSBPcmRlciwKICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsKICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCArIEdlbm90eXBlLAogICAgICAgICAgICAgc2NhbGVzID0gImZyZWVfeCIsCiAgICAgICAgICAgICBucm93ID0gMykgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKwogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAsIDApKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpCmdncGxvdGx5KHAxKQpgYGAKCmBgYHtyIG1lYW5zX28sIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxyYSA8LSByYV9tZWx0KHJhID0gcmFfbywKICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNtcGwsCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikKCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IGxyYSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9yZGVyID0gbHJhJE9yZGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkKbXVbLCB0b3RhbCA6PSBzdW0oeCksCiAgIGJ5ID0gIk9yZGVyIl0KdWwgPC0gdW5pcXVlKG11WywgYygiT3JkZXIiLCAKICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pCnVsIDwtIHVsW29yZGVyKHRvdGFsKSxdCm11JE9yZGVyIDwtIGZhY3RvcihtdSRPcmRlciwKICAgICAgICAgICAgICAgICAgIGxldmVsID0gdWwkT3JkZXIpCm11JHRvdGFsIDwtIE5VTEwKCmRhdGF0YWJsZShtdSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXIgPSBsaXN0KGxpc3QoMywgJ2Rlc2MnKSkpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNSwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpgYGB7ciBtZWFuc19vX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkKCnAwIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0gV2VlaywKICAgICAgICAgICAgICAgICB5ID0geCwKICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsKICBmYWNldF93cmFwKH4gT3JkZXIsCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArCiAgZ2VvbV9saW5lKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBUcnRfR2Vub3R5cGUpLAogICAgICAgICAgICAgc2hhcGUgPSAyMSwKICAgICAgICAgICAgIHNpemUgPSAyLAogICAgICAgICAgICAgYWxwaGEgPSAwLjUsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKCnRpZmYoZmlsZW5hbWUgPSAidG1wL3d0X09yZGVyX292ZXJfdGltZS50aWZmIiwKICAgICBoZWlnaHQgPSA1LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDApCmdyYXBoaWNzLm9mZigpCgpwcmludChwMCkKYGBgCgpgYGB7ciBtZWFuc19vX3AxLCBmaWcuaGVpZ2h0ID0gNSwgZmlnLndpZHRoID0gOX0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBPcmRlciwKICAgICAgICAgICAgICAgICBjb2xvciA9IFRydF9HZW5vdHlwZSwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9PcmRlcl9yYS50aWZmIiwKICAgICBoZWlnaHQgPSA0LAogICAgIHdpZHRoID0gNywKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDEpCmdyYXBoaWNzLm9mZigpCgpnZ3Bsb3RseShwMSkKYGBgCgojIyAzLiBGYW1pbHkKYGBge3IgY291bnRzX2YsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xNSxmaWcuaGVpZ2h0PTE1fQpjb3VudHNfZiA8LSBjb3VudHNfYnlfdGF4X3JhbmsoZHQxID0gb3R1MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiRmFtaWx5IikKcmFfZiA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfZikKCnRheC5yYW5rcyA8LSB1bmlxdWUob3R1MVssIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZhbWlseSIpXSkKCnJhX2YgPC0gbWVyZ2UodGF4LnJhbmtzLAogICAgICAgICAgICAgIHJhX2YsCiAgICAgICAgICAgICAgYnkgPSAiRmFtaWx5IikKCnRvdGFsIDwtIHJvd1N1bXMocmFfZlssIDM6bmNvbChyYV9mKV0pCgpyYV9mJEZhbWlseSA8LSBmYWN0b3IocmFfZiRGYW1pbHksCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX2YkRmFtaWx5W29yZGVyKHRvdGFsKV0pCgpyYV9mJFBoeWx1bSA8LSBmYWN0b3IocmFfZiRQaHlsdW0sCiAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMgPSB1bmlxdWUocmFfZiRQaHlsdW1bb3JkZXIodG90YWwpXSkpCnRtcCA8LSBtZWx0LmRhdGEudGFibGUoZGF0YSA9IHJhX2YsCiAgICAgICAgICAgICAgICAgICAgICAgaWQudmFycyA9IDE6MiwKICAgICAgICAgICAgICAgICAgICAgICBtZWFzdXJlLnZhcnMgPSAzOm5jb2woY291bnRzX2YpLAogICAgICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlLm5hbWUgPSAiU0FNUExFX05BTUUiLAogICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLm5hbWUgPSAiUkEiKQoKdG1wIDwtIG1lcmdlKGRhdGEudGFibGUoU0FNUExFX05BTUUgPSBzbXBsJFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICBXRUVLID0gc21wbCRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICBUUkVBVE1FTlQgPSBzbXBsJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgR2Vub3R5cGUgPSBzbXBsJEdlbm90eXBlKSwKICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCiMgUGxvdCBzYW1wbGVzCnAxIDwtIGdncGxvdCh0bXAsCiAgICAgICAgICAgICBhZXMoeCA9IFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgIHkgPSBSQSwKICAgICAgICAgICAgICAgICBmaWxsID0gRmFtaWx5LAogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKwogIGZhY2V0X3dyYXAofiBXRUVLICsgVFJFQVRNRU5UICsgR2Vub3R5cGUsCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwKICAgICAgICAgICAgIG5yb3cgPSAzKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKZ2dwbG90bHkocDEpCmBgYAoKYGBge3IgbWVhbnNfZiwgZWNobyA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRX0KbHJhIDwtIHJhX21lbHQocmEgPSByYV9mLAogICAgICAgICAgICAgICBzYW1wbGVzID0gc21wbCwKICAgICAgICAgICAgICAgc2FtcGxlX25hbWUgPSAiU0FNUExFX05BTUUiKQoKbXUgPC0gZGF0YS50YWJsZShhZ2dyZWdhdGUobHJhJFJBLAogICAgICAgICAgICAgICAgICAgICAgICAgICBieSA9IGxpc3QoV2VlayA9IGxyYSRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVHJlYXRtZW50ID0gbHJhJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gbHJhJEdlbm90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbHJhJEZhbWlseSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9ICJtZWFuIikpCm11WywgdG90YWwgOj0gc3VtKHgpLAogICBieSA9ICJGYW1pbHkiXQp1bCA8LSB1bmlxdWUobXVbLCBjKCJGYW1pbHkiLCAKICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pCnVsIDwtIHVsW29yZGVyKHRvdGFsKSxdCm11JEZhbWlseSA8LSBmYWN0b3IobXUkRmFtaWx5LAogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRGYW1pbHkpCm11JHRvdGFsIDwtIE5VTEwKCmRhdGF0YWJsZShtdSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5ID0gbGlzdChsaXN0KDMsICdkZXNjJykpKSkgJT4lCiAgZm9ybWF0Q3VycmVuY3koY29sdW1ucyA9IDUsCiAgICAgICAgICAgICAgICAgY3VycmVuY3kgPSAiIiwKICAgICAgICAgICAgICAgICBtYXJrID0gIiwiLAogICAgICAgICAgICAgICAgIGRpZ2l0cyA9IDIpCmBgYAoKTk9URTogb25seSB0aGUgZmlyc3QgMjQgZmFtaWxpZXMgaGFkIGxhcmdlIGVub3VnaCBjb3VudHMgLSBwbG90aW5nIG9ubHkgdGhlbS4gIAogIApgYGB7ciBtZWFuc19mX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkKbXUxIDwtIGRyb3BsZXZlbHMobXVbRmFtaWx5ICVpbiUgbGV2ZWxzKG11JEZhbWlseSlbbmxldmVscyhtdSRGYW1pbHkpOihubGV2ZWxzKG11JEZhbWlseSkgLSAyNCldLCBdKQoKcDAgPC0gZ2dwbG90KG11MSwKICAgICAgICAgICAgIGFlcyh4ID0gV2VlaywKICAgICAgICAgICAgICAgICB5ID0geCwKICAgICAgICAgICAgICAgICBncm91cCA9IFRydF9HZW5vdHlwZSkpICsKICBmYWNldF93cmFwKH4gRmFtaWx5LAogICAgICAgICAgICAgc2NhbGUgPSAiZnJlZV95IikgKwogIGdlb21fbGluZShwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKDAuMykpICsKICBnZW9tX3BvaW50KGFlcyhmaWxsID0gVHJ0X0dlbm90eXBlKSwKICAgICAgICAgICAgIHNoYXBlID0gMjEsCiAgICAgICAgICAgICBzaXplID0gMiwKICAgICAgICAgICAgIGFscGhhID0gMC41LAogICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiIikgKwogIHNjYWxlX3lfY29udGludW91cygiUmVsYXRpdmUgQWJ1bmRhbmNlICglKSIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhqdXN0ID0gMSkpCgp0aWZmKGZpbGVuYW1lID0gInRtcC93dF9GYW1pbHlfb3Zlcl90aW1lLnRpZmYiLAogICAgIGhlaWdodCA9IDcsCiAgICAgd2lkdGggPSA5LAogICAgIHVuaXRzID0gImluIiwKICAgICByZXMgPSA2MDAsCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQpwcmludChwMCkKZ3JhcGhpY3Mub2ZmKCkKCnByaW50KHAwKQpgYGAKCmBgYHtyIG1lYW5zX2ZfcDEsIGZpZy5oZWlnaHQgPSA1LCBmaWcud2lkdGggPSA5fQpwMSA8LSBnZ3Bsb3QobXUxLAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBGYW1pbHksCiAgICAgICAgICAgICAgICAgY29sb3IgPSBUcnRfR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfRmFtaWx5X3JhLnRpZmYiLAogICAgIGhlaWdodCA9IDQsCiAgICAgd2lkdGggPSA3LAogICAgIHVuaXRzID0gImluIiwKICAgICByZXMgPSA2MDAsCiAgICAgY29tcHJlc3Npb24gPSAibHp3K3AiKQpwcmludChwMSkKZ3JhcGhpY3Mub2ZmKCkKCmdncGxvdGx5KHAxKQpgYGAKCiMjIDQuIEdlbnVzCmBgYHtyIGNvdW50c19nLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSxmaWcud2lkdGg9MTUsZmlnLmhlaWdodD0xNX0KY291bnRzX2cgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dyX2J5ID0gIkdlbnVzIikKcmFfZyA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfZykKCnRheC5yYW5rcyA8LSB1bmlxdWUob3R1MVssIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkdlbnVzIildKQoKcmFfZyA8LSBtZXJnZSh0YXgucmFua3MsCiAgICAgICAgICAgICAgcmFfZywKICAgICAgICAgICAgICBieSA9ICJHZW51cyIpCgp0b3RhbCA8LSByb3dTdW1zKHJhX2dbLCAzOm5jb2wocmFfZyldKQoKcmFfZyRHZW51cyA8LSBmYWN0b3IocmFfZyRHZW51cywKICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gcmFfZyRHZW51c1tvcmRlcih0b3RhbCldKQoKcmFfZyRQaHlsdW0gPC0gZmFjdG9yKHJhX2ckUGh5bHVtLAogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gdW5pcXVlKHJhX2ckUGh5bHVtW29yZGVyKHRvdGFsKV0pKQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9nLAogICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSAxOjIsCiAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gMzpuY29sKGNvdW50c19nKSwKICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwKICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gIlJBIikKCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc21wbCRTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgV0VFSyA9IHNtcGwkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc21wbCRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgIEdlbm90eXBlID0gc21wbCRHZW5vdHlwZSksCiAgICAgICAgICAgICB0bXAsCiAgICAgICAgICAgICBieSA9ICJTQU1QTEVfTkFNRSIpCgojIFBsb3Qgc2FtcGxlcwpwMSA8LSBnZ3Bsb3QodG1wLAogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICB5ID0gUkEsCiAgICAgICAgICAgICAgICAgZmlsbCA9IEdlbnVzLAogICAgICAgICAgICAgICAgIGNvbG9yID0gUGh5bHVtKSkgKwogIGZhY2V0X3dyYXAofiBXRUVLICsgVFJFQVRNRU5UICsgR2Vub3R5cGUsCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwKICAgICAgICAgICAgIG5yb3cgPSAzKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKZ2dwbG90bHkocDEpCmBgYAoKCmBgYHtyIG1lYW5zX2csIGVjaG8gPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0V9CmxyYSA8LSByYV9tZWx0KHJhID0gcmFfZywKICAgICAgICAgICAgICAgc2FtcGxlcyA9IHNtcGwsCiAgICAgICAgICAgICAgIHNhbXBsZV9uYW1lID0gIlNBTVBMRV9OQU1FIikKCm11IDwtIGRhdGEudGFibGUoYWdncmVnYXRlKGxyYSRSQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgYnkgPSBsaXN0KFdlZWsgPSBscmEkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRyZWF0bWVudCA9IGxyYSRUUkVBVE1FTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZW5vdHlwZSA9IGxyYSRHZW5vdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdlbnVzID0gbHJhJEdlbnVzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRlVOID0gIm1lYW4iKSkKbXVbLCB0b3RhbCA6PSBzdW0oeCksCiAgIGJ5ID0gIkdlbnVzIl0KdWwgPC0gdW5pcXVlKG11WywgYygiR2VudXMiLCAKICAgICAgICAgICAgICAgICAgICAidG90YWwiKV0pCnVsIDwtIHVsW29yZGVyKHRvdGFsKSxdCm11JEdlbnVzIDwtIGZhY3RvcihtdSRHZW51cywKICAgICAgICAgICAgICAgICAgIGxldmVsID0gdWwkR2VudXMpCm11JHRvdGFsIDwtIE5VTEwKCmRhdGF0YWJsZShtdSwKICAgICAgICAgIHJvd25hbWVzID0gRkFMU0UsCiAgICAgICAgICBjYXB0aW9uID0gIlRheG9ub21pYyAgY291bnQgdGFibGUiLAogICAgICAgICAgY2xhc3MgPSAiY2VsbC1ib3JkZXIgc3RyaXBlIiwKICAgICAgICAgIG9wdGlvbnMgPSBsaXN0KHNlYXJjaCA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFnZUxlbmd0aCA9IDEwLAogICAgICAgICAgICAgICAgICAgICAgICAgR2VudXMgPSBsaXN0KGxpc3QoMywgJ2Rlc2MnKSkpKSAlPiUKICBmb3JtYXRDdXJyZW5jeShjb2x1bW5zID0gNSwKICAgICAgICAgICAgICAgICBjdXJyZW5jeSA9ICIiLAogICAgICAgICAgICAgICAgIG1hcmsgPSAiLCIsCiAgICAgICAgICAgICAgICAgZGlnaXRzID0gMikKYGBgCgpgYGB7ciBtZWFuc19nX3AwLCBmaWcud2lkdGggPSA5LCBmaWcuaGVpZ2h0ID0gN30KbXUkVHJ0X0dlbm90eXBlIDwtIGZhY3RvcihwYXN0ZShtdSRUcmVhdG1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXUkR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwID0gIl8iKSkKbXUxIDwtIGRyb3BsZXZlbHMobXVbR2VudXMgJWluJSBsZXZlbHMobXUkR2VudXMpW25sZXZlbHMobXUkR2VudXMpOihubGV2ZWxzKG11JEdlbnVzKSAtIDM1KV0sIF0pCgpwMCA8LSBnZ3Bsb3QobXUxLAogICAgICAgICAgICAgYWVzKHggPSBXZWVrLAogICAgICAgICAgICAgICAgIHkgPSB4LAogICAgICAgICAgICAgICAgIGdyb3VwID0gVHJ0X0dlbm90eXBlKSkgKwogIGZhY2V0X3dyYXAofiBHZW51cywKICAgICAgICAgICAgIHNjYWxlID0gImZyZWVfeSIpICsKICBnZW9tX2xpbmUocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgwLjMpKSArCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IFRydF9HZW5vdHlwZSksCiAgICAgICAgICAgICBzaGFwZSA9IDIxLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UoMC4zKSkgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfR2VudXNfb3Zlcl90aW1lLnRpZmYiLAogICAgIGhlaWdodCA9IDksCiAgICAgd2lkdGggPSAxMiwKICAgICB1bml0cyA9ICJpbiIsCiAgICAgcmVzID0gNjAwLAogICAgIGNvbXByZXNzaW9uID0gImx6dytwIikKcHJpbnQocDApCmdyYXBoaWNzLm9mZigpCgpwcmludChwMCkKYGBgCgpgYGB7ciBtZWFuc19nX3AxLCBmaWcuaGVpZ2h0ID0gOSwgZmlnLndpZHRoID0gOX0KcDEgPC0gZ2dwbG90KG11MSwKICAgICAgICAgICAgIGFlcyh4ID0geCwKICAgICAgICAgICAgICAgICB5ID0gR2VudXMsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBUcnRfR2Vub3R5cGUsCiAgICAgICAgICAgICAgICAgc2hhcGUgPSBXZWVrKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9jb250aW51b3VzKCJSZWxhdGl2ZSBBYnVuZGFuY2UgKCUpIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKQoKdGlmZihmaWxlbmFtZSA9ICJ0bXAvd3RfR2VudXNfcmEudGlmZiIsCiAgICAgaGVpZ2h0ID0gOSwKICAgICB3aWR0aCA9IDksCiAgICAgdW5pdHMgPSAiaW4iLAogICAgIHJlcyA9IDYwMCwKICAgICBjb21wcmVzc2lvbiA9ICJsencrcCIpCnByaW50KHAxKQpncmFwaGljcy5vZmYoKQoKZ2dwbG90bHkocDEpCmBgYAoKCgojIFNlc3Npb24gSW5mb3JtYXRpb24KYGBge3IgaW5mbyxldmFsPVRSVUV9CnNlc3Npb25JbmZvKCkKYGBg